//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#ifndef __USBAPI_H_
#define __USBAPI_H_

//usb headers files
#include "drv_glob.h"
#include <bulverde.h>
#include <Bvd1.h>       //UDC defined in
#include <BVD_UDC_Bits.h>

#include "usb11.h"
#include "usbdbg.h"

#define DEV_USB_FUNC_NAME L"usbfunc"

//Define The Endpoint FIFO Length
#define EP0Len          16
#define EP1Len          64
#define EP1DBLen        128
#define EP2Len          64
#define EP2DBLen        128

//Define operate code
#define USB_OP_DISCONNECT 0x0000B001
#define USB_OP_RECONNECT  0x0000B002
#define USB_EMU_TYPE      0x0000B003


#define MASS_INIT          0x0000C001
#define MASS_STOP          0x0000C002
#define MASS_WAKE          0x0000C003
#define MASS_STOP_BLKCLS   0x0000C004
#define MASS_WAKE_BLKOPN   0x0000C005

#define UCDC_INIT       0x0000D001
#define UCDC_STOP       0x0000D002
#define UCDC_WAKE       0x0000D003
#define UCDC_SET_SYNC   0x0000D004
#define UCDC_SET_ASYNC  0x0000D005
#define UCDC_SET_PRIF   0x0000D006
#define UCDC_CLR_BUF    0x0000D007

#define UDC_STATE(x) x->eState

#define MINI(x,y)  (x > y) ? y : x

/*
 * @doc HWINTERNAL
 * @struct SER_INFO | Private structure.
 */
typedef struct __SER_INFO {
    XLLP_INTC_T         *pINTCRegs;    // Interrupt Controller registers base address
    UDC_REGS            *pUDCRegs;     // UDC registers base address
    XLLP_CLKMGR_T       *pCLKRegs;     //CLK Base Address
    int		            eState;		   // @field Current EP0 state machine

// EP0 Data Xfer info
    int		nXmitLength;		// @field Current EP0 xfer length
    PByte   pXmitData;			// @field Pointer to xmit data for EP0
    int		nXmitIndex;			// @field Index into the current EP0 xmit buffer
    int		nXmitReq;			// @field Requested amount of data on EP0
    SetupPKG	dReq;		        // @field USB endpoint 0 command
} SER_INFO, *PSER_INFO;

typedef struct __PIPE_INFO {
    UInt32  Pipenum;
    UInt32  Pipelen;
} PIPE_INFO, *PPIPE_INFO;


typedef  Boolean (*HandleVendorReQ)(UInt8 Arg, UInt8 **ppbData, UInt16 *pwLen, UInt16 *pwTotLen);

class CUsbApi : public CDeviceDriver{
public:
    CARAPI Read(
        /* [in] */ Int64 u64Offset,
        /* [in] */ Int32 bytesToRead,
        /* [out] */ MemoryBuf * pBuffer,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI Write(
        /* [in] */ Int64 u64Offset,
        /* [in] */ const MemoryBuf & buffer,
        /* [out] */ Int32 * pBytesWritten,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI Control(
        /* [in] */ Handle32 nControlCode,
        /* [in] */ const MemoryBuf & inBuffer,
        /* [out] */ MemoryBuf * pOutBuffer,
        /* [out] */ IEvent * * ppCompletionEvent);

    virtual void Dispose();

    public:
        CARAPI Initialize();
        CARAPI DeviceStart();

        void SetupDevice(  int devtype,
                          descriptor *Desc,
                           HandleVendorReQ verdorhandle,
                           DzEvent *pEv);

        ECode RegisterDeviceIsr();
        ECode HandleIsr(bool *pbNotMyIntr);
        INTRTYPE GetIntrType();
        void HandleCtrlXfer(INTRTYPE intr);
        void HandleInterrupt();
        void InterruptDone();

        ECode PowerOnUSB();
        ECode PowerOffUSB();
        void SysIRQEnableUSB();
        void SysIRQDisableUSB();
        void EpEnableIRQ(UInt32 EpNum);
        void EpDisableIRQ(UInt32 EpNum);
        void ClkEnableUSB();
        void ClkDisableUSB();
        void UsbHwSetUp();

        //endpoint0 functions
        void ServiceEP0();
        void ProcessEP0InStatus();
        void ProcessEP0OutStatus();
        void ProcessEP0Setup();
        void XmitEP0Data();
        Boolean ParseSetup();
        int  getCommandEightBytes(void * dataP);
        int  getCommand(void * dataP);


        //bulk endpoint functions
       // int  WaitForSignal(UInt32 PipeNum);
       //UInt32 SA_USB_RxIntHandler(UInt8 *pRxBuffer, UInt32 Bufflen);
        UInt32 EPxReceiveData(UInt32 ep, UInt8 *pRxBuf, UInt32 cbSize);
        UInt32 EPxTransmitData(UInt32 ep, UInt8 *pTxBuf, UInt32 cbSize, int pooling);
        UInt32 HandleDataIn(UInt8 *pTxBuffer, UInt32 BufLen, int pooling);
        UInt32 HandleDataOut(UInt8 *pRxBuffer, UInt32 Bufflen);
        void GetPipeInfo(PPIPE_INFO Ctl, PPIPE_INFO Din, PPIPE_INFO Dout);
        void StallPipe(UInt32 PortNum);
        //void ConfigPipe(CDeviceCondition *pEvBI, CDeviceCondition *pEvBo);
        void ConfigPipe();
        void ClearPipeStall(UInt32 PortNum);
        void SoftDisconnect();
        void ReConnect();
//////////////////////////////////////////////
public:
        DzEvent      *m_pCondition;
        descriptor   *m_pDesc;
        HandleVendorReQ  m_VendorHandle;
        int           m_DevType;
        Boolean          m_IsISRRegiser;
        PSER_INFO pHWHead;
};
#endif //__USBAPI_H_

